# -*- coding: utf-8 -*-
import json

from odoo import models, fields, api
from odoo.exceptions import UserError
from odoo.tools import float_round, float_compare, float_is_zero


class MrpConsumeLine(models.Model):
    _name = 'mrp.consume.line'

    product_id = fields.Many2one(comodel_name='product.product', string=u'产品')
    require_qty = fields.Float(string=u'需求', compute='_compute_qty')
    max_required_qty=fields.Float(string=u'最大需求数量',compute='_compute_max_required_qty')
    max_consume_qty=fields.Float(string=u'最大消耗数量',compute='_compute_max_required_qty')
    # 根据bom配比计算最大能领取的数量
    def _compute_max_required_qty(self):
        for record in self:
            line=record.production_id.bom_id.bom_line_ids.filtered(lambda x:x.product_id==record.product_id)
            max_required_qty=line.product_qty*(1+line.scrap_rate/100)*record.production_id.product_qty
            record.max_required_qty=max_required_qty


    picking_qty = fields.Float(string=u'已发数量', compute='_compute_qty')
    unpicking_qty = fields.Float(string=u'未领', compute='_compute_unpicking_qty')

    repicking_qty = fields.Float(string=u'已补', compute='_compute_repicking_qty')
    return_qty = fields.Float(string=u'已退', compute='_compute_return_qty')
    scrap_qty=fields.Float(string=u'已报废', compute='_compute_scarp_qty')
    can_scrap_qty=fields.Float(string=u'可报废数量',compute='_compute_can_scrap_qty')
    can_output_qty=fields.Float(string=u'可数量',compute='_compute_output')

    def _compute_output(self):
        for r in self:
            r.can_output_qty=r.picking_qty-r.consume_qty-r.scrap_qty

    def _compute_can_scrap_qty(self):
        for record in self:
            record.can_scrap_qty=record.picking_qty-record.scrap_qty-record.consume_qty
    max_output_qty=fields.Float(compute='compute_max_output_qty')
    # 根据已领数量和bom
    def compute_max_output_qty(self):
        for record in self:
            line = record.production_id.bom_id.bom_line_ids.filtered(lambda x: x.product_id == record.product_id)

            record.max_output_qty=record.picking_qty/(line.product_qty/line.bom_id.product_qty)





    consume_qty = fields.Float(string=u'投料', compute='_compute_qty')
    production_id = fields.Many2one(string=u'MO', comodel_name='mrp.production',ondelete='cascade')


    move_ids = fields.One2many('stock.move', string=u'Raw Materials', compute='_compute_move_ids')
    qty_available = fields.Float(string=u'库存', related='product_id.qty_available')

    ### 按钮事件
    def show_product_id(self):
        self.ensure_one()
        return {
            'name': self.product_id.name,
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': self.product_id._name,
            'res_id': self.product_id.id,
            'type': 'ir.actions.act_window',
            'target': 'current',
        }

    def show_qty_available(self):
        self.ensure_one()
        action = self.env.ref('stock.product_open_quants').read()[0]
        action['domain'] = [('product_id', 'in', self.product_id.ids)]
        action['context'] = {'search_default_locationgroup': 1, 'search_default_internal_loc': 1}
        return action

    def show_qty_picking_available(self):
        self.ensure_one()
        pickings = self.production_id.get_prepare_pickings()
        location = self.env['stock.location']
        if pickings:
            location = pickings[0].location_dest_id  # 备料单的目的位置

        action = self.env.ref('stock.product_open_quants').read()[0]
        action['domain'] = [('product_id', 'in', self.product_id.ids), ('location_id', '=', location.id)]
        action['context'] = {'search_default_locationgroup': 1, 'search_default_internal_loc': 1}
        return action

    def show_qty_reservation(self):
        self.ensure_one()
        pickings = self.env['stock.picking']
        quants = self.search_quants(self.production_id.picking_type_id.warehouse_id.lot_stock_id)
        reservations = quants.mapped('reservation_id')
        if reservations:
            pickings = reservations.mapped('picking_id')

        action = self.env.ref('stock.action_picking_tree_all').read()[0]
        if len(pickings) > 1:
            action['domain'] = [('id', 'in', pickings.ids)]
        elif pickings:
            action['views'] = [(self.env.ref('stock.view_picking_form').id, 'form')]
            action['res_id'] = pickings.id
        else:
            action['domain'] = [('id', 'in', pickings.ids)]
        return action

    ####

    def _compute_repicking_qty(self):
        stock_move = self.env['stock.move']
        for line in self:
            repicking_moves = stock_move.search([('re_picking_production_id', '=', line.production_id.id),
                                                 ('product_id', '=', line.product_id.id),
                                                 ('state', '=', 'done')])
            line.repicking_qty = sum(repicking_moves.mapped('product_qty')) or 0

    def _compute_return_qty(self):
        stock_move = self.env['stock.move']
        for line in self:
            return_moves = stock_move.search([('return_raw_production_id', '=', line.production_id.id),
                                              ('product_id', '=', line.product_id.id),
                                              ('state', '=', 'done')])
            line.return_qty = sum(return_moves.mapped('product_qty')) or 0

    def _compute_unpicking_qty(self):
        for record in self:
            qty=record.max_required_qty-record.picking_qty+record.return_qty+record.scrap_qty
            record.unpicking_qty=qty
        # if float_compare(qty,0,precision_digits=1)>0:
        #     raise UserError(self.product_id.name+'领料数量不能大于最大需求数量')


    def _compute_scarp_qty(self):
        stock_move = self.env['stock.move']
        for line in self:
            scrap_moves = stock_move.search([('scarp_production_id', '=', line.production_id.id),
                                              ('product_id', '=', line.product_id.id),
                                              ('state', '=', 'done')])
            line.scrap_qty = sum(scrap_moves.mapped('product_qty')) or 0

    def _compute_qty_detail(self):
        for line in self:
            pickings = line.production_id.get_prepare_pickings()
            warehouse = line.product_id.categ_id.main_warehouse_id
            if pickings:
                location = pickings[0].location_dest_id  # 备料单的目的位置
            else:
                continue
                # location = location.search([('name', 'ilike', u'领料区'), ('warehouse_id', '=', warehouse.id)], limit=1)

            line.qty_picking_available = line.product_id.with_context({'location': location.id}).qty_available
            qty_stock_available = line.product_id.with_context({'location': warehouse.lot_stock_id.id}).qty_available

            quants = line.search_quants(warehouse.lot_stock_id)
            line.qty_reservation = sum(quants.mapped('qty')) or 0
            line.qty_move_reservation = sum(
                quants.filtered(lambda x: x.reservation_id.picking_id in pickings).mapped('qty')) or 0
            # 可用 = 库存 - 总预留

            line.qty_can_use = qty_stock_available - line.qty_reservation

    def search_quants(self, location_id):
        self.ensure_one()

        quant = self.env['stock.quant'].search([('reservation_id', '!=', False),
                                                ('location_id', '=', location_id.id),
                                                ('product_id', '=', self.product_id.id)
                                                ])
        return quant

    def _compute_qty(self):
        for line in self:
            if line:
                consume_qty = 0
                require_qty = 0
                for move in line.move_ids:
                    if move.state != 'cancel':
                        require_qty += move.product_qty
                        if move.state == 'done':
                            consume_qty += move.product_qty
                        else:
                            consume_qty += move.quantity_done

                picking_moves = line.production_id.get_pick_moves().filtered(lambda x: x.product_id == line.product_id
                                                                                        and x.state != 'cancel' and not x.re_picking_production_id)
                self.env['stock.move'].search(
                        [('id', 'in', picking_moves.ids), ('state', '!=', 'cancel'),
                         ('re_picking_production_id', '=', False)])  # 领料
                # 領料數量= 領料單+補料單
                line.picking_qty = (sum(picking_moves.filtered(lambda x: x.state == 'done').mapped(
                    'product_qty') or []) or 0) + line.repicking_qty
                # line.prepare_qty = sum(prepare_moves.filtered(lambda x: x.state == 'done').mapped('product_qty' or [])) or 0

                # line.unpicking_qty = sum(
                #     picking_moves.filtered(lambda x: x.state != 'done').mapped('product_qty') or []) or 0
                # line.unprepare_qty = sum(
                #     prepare_moves.filtered(lambda x: x.state != 'done').mapped('product_qty' or [])) or 0

                bom_line = line.production_id.bom_id.bom_line_ids.filtered(lambda x: x.product_id == line.product_id)
                main_product_moves = line.production_id.move_finished_ids.filtered(
                    lambda x: x.product_id.id == line.production_id.product_id.id)

                output= sum(main_product_moves.mapped('quantity_done'))

                consume_qty = output*(bom_line.product_qty / bom_line.bom_id.product_qty)

                line.consume_qty = consume_qty
                line.require_qty = require_qty

    def _compute_move_ids(self):
        stock_move = self.env['stock.move']
        for line in self:
            if line:
                moves = stock_move.search([('raw_material_production_id', '=', line.production_id.id),
                                           ('scrapped', '=', False),
                                           ('product_id', '=', line.product_id.id)])
                line.move_ids = moves.ids


